
import { ChatBlock } from "./block/block"
import { ChatSidebar } from "./components/chat_sidebar"
import { useMenus } from "./hooks/menus"
import { useCallback, useEffect, useMemo, useRef, useState } from "react"
import { Chat } from "../chat"
import { Friend } from "../friend"
import { Group } from "../group"
import { Collection } from "../collection"
import { Notification, Button, Avatar, Message } from '@arco-design/web-react';
import http, { IM_SERVER_URL } from "../../http/index"
import { useDispatch, useSelector } from "react-redux"
import { setCurrent, updateMenusNum } from "../../store/features/menus"


import IMSDK from '../../sdk/index'
import { Conversation, ConversationType, MessageState, MessageType } from "../../domain/im/entity"
import { addConversation, fetchConversationList, refreshConversationByTargetId, updateLastMessage, updateLastMessageaddNum } from "../../store/features/conversation"
import { refreshFriendList } from "../../store/features/friend"
import { addMessageState, openMessage, updateMessageState } from "../../store/features/message"
import { IconVideoCamera } from "@arco-design/web-react/icon"
import { addAnswer, addCandidate, addOffer, setNoticeId, updateVideoUserId } from "../../store/features/user"
import { WebRtcModel } from "../chat/components/webrtc_model"
import e from "express"


import MBProtocalFactory from '../../sdk/module/mb_constants'

import uuid from "../../sdk/module/uuid";

export const Home = () => {
    const useMenusHook = useMenus();


    // 控制视频显示
    const [visible, setVisible] = useState(false);
    const [targetId, setTargetId] = useState<any>("");;




    const { token, user } = useSelector((state: any) => state.user.value)
    const { menus } = useSelector((state: any) => state.menus.value)


    const message = useSelector((state: any) => state.message.value)


    const { noticeId, visible: VideoVisible } = useSelector((state: any) => state.user.value);


    // 会话列表
    const { list, current } = useSelector((state: any) => state.conversation.value);



    const dispatch = useDispatch();



    const handleMessagesReceived = useCallback((theFingerPrint: any) => {
        const str = localStorage.getItem("messages");
        if (str) {
            const targetId = `${list[current].targetId}`;
            let messages = JSON.parse(str);
            const array = messages[`${targetId}`];

            var state = false;
            for (var item of array) {
                if (item.fp === theFingerPrint) {
                    state = true;
                    item.state = MessageState.arrive;
                    const timestamp = new Date(item.timestamp).getTime();
                    const lastMessage = JSON.stringify(item);
                    dispatch(updateLastMessage({ targetId, timestamp, lastMessage }))
                    dispatch(fetchConversationList(list[current].targetId))
                }
            }
            if (state) {
                messages[`${list[current].targetId}`] = array;
                dispatch(updateMessageState({ message: messages }));
            }
        }
    }, [list, current, dispatch]);



    const handleCallbackOnIMData = useCallback((data: any) => {


        if (data.typeu == MessageType.removeUserGroup) {
            const fetchMessage = async () => {
                const respones = await http.get("/message/list?targetId=" + list[current].targetId)
                dispatch(openMessage({ messages: respones.data, targetId: list[current].targetId }));
            }
            fetchMessage();
            const dataContent = JSON.parse(data.dataContent);
            dispatch(fetchConversationList(0))
            return;

        }

        if (data.typeu == MessageType.invitationGroup) {
            console.log("收到邀请人信息");
            const fetchMessage = async () => {
                const respones = await http.get("/message/list?targetId=" + list[current].targetId)
                dispatch(openMessage({ messages: respones.data, targetId: list[current].targetId }));
            }
            fetchMessage();
            const dataContent = JSON.parse(data.dataContent);
            dispatch(fetchConversationList(list[current].targetId))
            return;
        }


        if (data.typeu == MessageType.noticeGroup) {
            const dataContent = JSON.parse(data.dataContent)
            if (dataContent.groupId == list[current].targetId) {
                const fetchMessage = async () => {
                    console.log("查询聊天记录")
                    const respones = await http.get("/message/list?targetId=" + list[current].targetId)
                    console.log(respones.data);
                    dispatch(openMessage({ messages: respones.data, targetId: list[current].targetId }));
                }
                fetchMessage();
                dispatch(fetchConversationList(list[current].targetId));
            } else {
                dispatch(fetchConversationList(list[current].targetId));
            }

            return;
        }

        if (data.typeu == MessageType.updateNameGroup) {
            const dataContent = JSON.parse(data.dataContent)
            console.log("用户修改了群名称", data, dataContent);
            if (dataContent.groupId == list[current].targetId) {
                const fetchMessage = async () => {
                    console.log("查询聊天记录")
                    const respones = await http.get("/message/list?targetId=" + list[current].targetId)
                    console.log(respones.data);
                    dispatch(openMessage({ messages: respones.data, targetId: list[current].targetId }));
                }
                fetchMessage();
                dispatch(fetchConversationList(list[current].targetId));
            } else {
                dispatch(fetchConversationList(list[current].targetId));
            }

            return;
        }

        if (data.typeu == MessageType.createGroup) {
            const fetchMessage = async () => {
                const respones = await http.get("/message/list?targetId=" + list[current].targetId)
                dispatch(openMessage({ messages: respones.data, targetId: list[current].targetId }));
            }
            fetchMessage();
            const dataContent = JSON.parse(data.dataContent);
            // 刷新会话
            dispatch(fetchConversationList(list[current].targetId))
            return;
        }

        if (data.typeu == MessageType.VideoCancel) {
            Notification.remove(noticeId);
            dispatch(updateVideoUserId({ visible: false }));
            Message.info({
                content: '对方已取消',
            });


            const fetchMessage = async () => {
                const respones = await http.get("/message/list?targetId=" + list[current].targetId)
                dispatch(openMessage({ messages: respones.data, targetId: list[current].targetId }));
            }

            fetchMessage();
            return;
        }



        if (data.typeu == MessageType.VideoBusyLine) {
            dispatch(updateVideoUserId({ visible: false }));
            Message.info({
                content: '对方正在通话',
            });

            const fetchMessage = async () => {
                const respones = await http.get("/message/list?targetId=" + list[current].targetId)
                dispatch(openMessage({ messages: respones.data, targetId: list[current].targetId }));
            }

            fetchMessage();
            return;
        }



        if (data.typeu == MessageType.VideoRefuse) {
            dispatch(updateVideoUserId({ visible: false }));
            Message.info({
                content: '对方已拒绝',
            });

            const fetchMessage = async () => {
                const respones = await http.get("/message/list?targetId=" + list[current].targetId)
                dispatch(openMessage({ messages: respones.data, targetId: list[current].targetId }));
            }

            fetchMessage();
            return;
        }



        if (data.typeu == MessageType.VideoHangUp) {
            dispatch(updateVideoUserId({ visible: false }));
            Message.info({
                content: '对方已挂断',
            });

            const fetchMessage = async () => {
                const respones = await http.get("/message/list?targetId=" + list[current].targetId)
                dispatch(openMessage({ messages: respones.data, targetId: list[current].targetId }));
            }

            fetchMessage();
            return;
        }



        if (data.typeu == MessageType.VideoInterrupt) {
            dispatch(updateVideoUserId({ visible: false }));
            Notification.remove(noticeId);
            Notification.error({
                title: '视频通话',
                content: `视频通话被中断`,
            });

            const fetchMessage = async () => {
                const respones = await http.get("/message/list?targetId=" + list[current].targetId)
                dispatch(openMessage({ messages: respones.data, targetId: list[current].targetId }));
            }

            fetchMessage();
            return;
        }



        if (data.typeu == MessageType.VideoNoResponse) {
            dispatch(updateVideoUserId({ visible: false }));

            if (data.dataContent == data.to) {
                Notification.error({
                    title: '视频通话',
                    content: `没人接听你的视频通话`,
                });
            }

            const fetchMessage = async () => {
                const respones = await http.get("/message/list?targetId=" + list[current].targetId)
                dispatch(openMessage({ messages: respones.data, targetId: list[current].targetId }));
            }

            fetchMessage();


            return;
        }

        if (data.typeu == MessageType.VideoOffer) {

            if (VideoVisible) return;

            const fetchUser = async () => {
                const response = await http.get(`/findUserById?id=${data.from}`);
                const userName = response.data.userName;
                const userPortrait = response.data?.userPortrait ?? "";
                const id = `${Date.now()}`;
                dispatch(setNoticeId({ noticeId: id }))
                Notification.info({
                    id,
                    className: 'p-5',
                    title: '视频通话',
                    content: `${userName}向你发起视频通话`,
                    closeIcon: <span className="text-gray-500">忽略</span>,
                    duration: 10000,
                    icon: <Avatar size={40} shape="square">
                        {
                            userPortrait ? <img src={userPortrait}></img> : userName
                        }
                    </Avatar>,
                    btn: (
                        <span>
                            <Button
                                type='secondary'
                                size='small'
                                onClick={() => {

                                    Notification.remove(id);

                                    const fp = JSON.parse(data.dataContent).fp;
                                    let p: any = MBProtocalFactory.createCommonData({
                                        dataContent: fp,
                                        from: IMSDK.getLoginInfo().loginUserId,
                                        fp: uuid.v1(),
                                        QoS: true,
                                        to: data.from,
                                        typeu: MessageType.VideoRefuse
                                    });
                                    IMSDK.sendData(p);

                                    const fetchMessage = async () => {
                                        const respones = await http.get("/message/list?targetId=" + list[current].targetId)
                                        dispatch(openMessage({ messages: respones.data, targetId: list[current].targetId }));
                                    }

                                    fetchMessage();
                                }}
                                style={{ margin: '0 12px' }}
                            >
                                拒绝
                            </Button>
                            <Button type='primary' size='small' onClick={() => {
                                const webrtc = JSON.parse(data.dataContent).type;
                                Notification.remove(id);
                                dispatch(updateVideoUserId({
                                    videoUserId: data.from,
                                    visible: true,
                                    call: "answer",
                                    offer: data,
                                    webrtc
                                }
                                ))
                            }}>
                                同意
                            </Button>
                        </span>
                    ),
                });
            }
            fetchUser();
        }

        if (data.typeu == MessageType.Candidate) {
            dispatch(addCandidate(data));
            return;
        }
        if (data.typeu == MessageType.VideoAnswer) {
            dispatch(addAnswer(data));
            return;
        }




        if (data.typeu == MessageType.TxtMsg || data.typeu == MessageType.SightMsg || data.typeu == MessageType.ImgMsg || data.typeu == MessageType.FileMsg) {
            const dataContent = JSON.parse(data.dataContent);
            const targetId = data.from == "0" ? dataContent.groupId : data.from;
            if (dataContent.from) {
                data.from = dataContent.from;
            }
            if (list[current].targetId == targetId) {
                const fetchMessage = async () => {
                    const respones = await http.get("/message/list?targetId=" + list[current].targetId)
                    dispatch(openMessage({ messages: respones.data, targetId: list[current].targetId }));
                }
                dispatch(fetchConversationList(list[current].targetId));
                fetchMessage();
            } else {
                dispatch(fetchConversationList(list[current].targetId));
            }
            return;
        }


        if (data.typeu == MessageType.AddFriend) {
            // 对方请求添加好友请求
            dispatch(updateMenusNum({ name: "好友", num: 1 }));
        }



        if (data.typeu == MessageType.VerifiedBy) {
            const userId = user.userId;
            const dataContent = JSON.parse(data.dataContent);

            const targetId = dataContent.receiveId == userId ? dataContent.senderId : dataContent.receiveId;
            const fetchUser = async () => {
                const response = await http.get(`/findUserById?id=${targetId}`);
                const conversation: Conversation = {
                    type: ConversationType.private,
                    lastMessage: JSON.stringify(data),
                    targetId: targetId,
                    userName: response.data.userName,
                    portrait: response.data?.userPortrait ?? "",
                    timestamp: new Date().getTime(),
                    unreadCount: 1
                };
                dispatch(addConversation(conversation))
                dispatch(refreshFriendList());
                const respones = await http.get("/message/list?targetId=" + conversation.targetId)
                dispatch(openMessage({ messages: respones.data, targetId: conversation.targetId }));
            }

            fetchUser();
        }

    }, [list, current, dispatch, noticeId, VideoVisible]);




    const callback_onMessagesLost = useCallback((datas: any) => {

        for (let fpItem of datas) {
            const str: any = localStorage.getItem("messages");
            const messagesMap = JSON.parse(str);
            const dataContent = JSON.parse(fpItem.dataContent);
            const messages = fpItem.to != '0' ? messagesMap[`${fpItem.to}`] : messagesMap[`${dataContent['groupId']}`]
            for (var item of messages) {
                if (item.fp == fpItem.fp) {
                    item.state = MessageState.error
                    localStorage.setItem("messages", JSON.stringify(messagesMap));
                    dispatch(updateMessageState({ message: { [`${fpItem.to == "0" ? dataContent['groupId'] : fpItem.to}`]: messages } }));
                }
            }
        }


    }, [list, current, dispatch, noticeId, VideoVisible]);





    useEffect(() => {
        // 拉去离线消息
        const fetchOffLine = async () => {
            const response: any = await http.get("message/offline")
            if (response.code == 200) {
                const index = response.data.findIndex((item: any) => item.typeu == MessageType.AddFriend)
                if (index != -1) {
                    dispatch(updateMenusNum({ name: "好友", num: 1 }));
                }
            }
        }

        fetchOffLine();


        const str = localStorage.getItem("user");
        if (!IMSDK._logined && str) {
            const { user, token } = JSON.parse(str);
            var loginInfo = { loginUserId: user.userId, loginToken: token };
            IMSDK.loginImpl(loginInfo, IM_SERVER_URL)
        }



    }, [])


    useEffect(() => {

        IMSDK.callback_onMessagesBeReceived = handleMessagesReceived
        IMSDK.callback_onIMData = handleCallbackOnIMData


        IMSDK.callback_onMessagesLost = callback_onMessagesLost;

    }, [handleMessagesReceived, handleCallbackOnIMData])



    const topRef = useRef(null);


    return <>
        <div ref={topRef}>

            <WebRtcModel />
            <ChatBlock>
                <ChatSidebar hook={useMenusHook}></ChatSidebar>

                <div style={{ display: useMenusHook.current === 0 ? 'block' : 'none' }}>
                    <Chat topRef={topRef} />
                </div>
                <div style={{ display: useMenusHook.current === 1 ? 'block' : 'none' }}>
                    <Friend />
                </div>
                <div style={{ display: useMenusHook.current === 2 ? 'block' : 'none' }}>
                    <Group />
                </div>
                <div style={{ display: useMenusHook.current === 3 ? 'block' : 'none' }}>
                    <Collection />
                </div>
            </ChatBlock>
        </div>

    </>
}